package com.edushare.activity;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.provider.MediaStore.MediaColumns;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.edushare.R;
import com.edushare.controller.GroupMediaController;
import com.edushare.controller.HttpUploader;
import com.edushare.controller.JSONParser;
import com.edushare.entity.GroupMedia;
import com.edushare.entity.ViewHolder;

public class GridViewActivity extends Activity {

	GridView gridView;

	private GroupMediaController gc = new GroupMediaController();
	ArrayList<GroupMedia> mediaList = new ArrayList<GroupMedia>();
	public static final String LOG_TAG = "EduShare";
	public static final String PICTURE_FILE_ID = "picture";
	public static final String TMP_FILE_NAME = ".unifiq";
	private static final int CAMERA_REQUEST_CODE = 666;
	private static final int GALLERY_REQUEST_CODE = 777;
	private static final int REPLACE_IMAGE_CODE = 555;
	private static final int ADD_MEDIA_CODE = 888;

	private static final Bitmap.CompressFormat COMPRESS_FORMAT = Bitmap.CompressFormat.PNG;
	private static final int COMPRESS_QUALITY = 100;

	private File mPictureFile;
	String imagename = "";
	int mediaID = 1;

	@Override
	public void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		setContentView(R.layout.grid);

		gridView = (GridView) findViewById(R.id.gridView1);
		// get media of the group to store in mediaList
		new LoadMedias().execute();

	}

	/**
	 * Starts draw activity with given background.
	 */
	private void draw() {
		if (mPictureFile != null) {
			Intent intent = new Intent(this, DrawActivity.class);
			intent.putExtra(PICTURE_FILE_ID, mPictureFile);
			startActivity(intent);
		}
	}

	/**
	 * Gets path of an image from the gallery.
	 * 
	 * @param uri
	 *            Image Uri
	 * @return Image absolute path
	 */
	private String getImagePath(final Uri uri) {
		String[] projection = { MediaColumns.DATA };
		Cursor cursor = getContentResolver().query(uri, projection, null, null,
				null);
		int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
		cursor.moveToFirst();
		return cursor.getString(column_index);
	}

	private String getRealPathFromURI(Uri contentUri) {

		String[] proj = { MediaColumns.DATA };
		android.database.Cursor cursor = getContentResolver().query(contentUri,
				proj, // Which
				// columns
				// to
				// return
				null, // WHERE clause; which rows to return (all rows)
				null, // WHERE clause selection arguments (none)
				null); // Order-by clause (ascending by name)
		int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
		cursor.moveToFirst();
		return cursor.getString(column_index);
	}

	/** Async task for loading medias into group list */
	class LoadMedias extends AsyncTask<String, String, String> {

		@Override
		protected String doInBackground(String... args) {
			// get intent values
			Intent i = getIntent();
			int gid = i.getExtras().getInt("groupid");
			// store list of media in medialist
			mediaList = gc.retrieveGroupsMedia(Integer.toString(gid));
			return null;
		}

		@Override
		protected void onPostExecute(String result) {

			ListAdapter myAdapter = new ListAdapter(getApplicationContext());
			gridView.setAdapter(myAdapter);
			myAdapter.notifyDataSetChanged();

			/** When grid item is clicked */
			gridView.setOnItemClickListener(new OnItemClickListener() {
				@Override
				public void onItemClick(AdapterView<?> parent, View v,
						int position, long id) {
					Toast.makeText(
							getApplicationContext(),
							((TextView) v.findViewById(R.id.grid_item_label))
									.getText(), Toast.LENGTH_SHORT).show();
				}
			});

			super.onPostExecute(result);
		}

		/**
		 * Before starting background thread Show Progress Dialog
		 * */
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}
	}

	/** Update Group Icon */
	class UpdateIcon extends AsyncTask<String, String, String> {

		@Override
		protected String doInBackground(String... args) {
			// TODO
			gc.updateGroupIcon(mediaID, imagename);
			return null;
		}

		@Override
		protected void onPostExecute(String file_url) {

			// Load bitmap from internet
			URL onLineURL;
			try {
				onLineURL = new URL(
						"http://unifiq.5kportal.com/images/post_images/"
								+ imagename);
			} catch (MalformedURLException e) {
				e.printStackTrace();
			}
		}

		/**
		 * Before starting background thread Show Progress Dialog
		 * */
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}
	}

	class UploadMedia extends AsyncTask<String, String, String> {

		ProgressDialog pd = new ProgressDialog(GridViewActivity.this);

		@Override
		protected void onPostExecute(String file_url) {
			pd.dismiss();
			if (file_url != null) {
				Toast.makeText(getApplicationContext(), "upload successfully",
						5).show();
			} else {
				Toast.makeText(getApplicationContext(), "fail to upload", 5)
						.show();
			}
		}

		/**
		 * Before starting background thread Show Progress Dialog
		 * */
		@Override
		protected void onPreExecute() {
			pd.setMessage("uploading media...");
			pd.show();
		}

		@Override
		protected String doInBackground(String... params) {
			ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			nameValuePairs.add(new BasicNameValuePair("imagePath",
					"http://unifiq.5kportal.com/images/post_images/"
							+ params[0]));
			nameValuePairs.add(new BasicNameValuePair("groupID", params[1]));

			JSONParser json = new JSONParser();
			JSONObject jsonObj = json
					.getJSONFromUrl(
							"http://unifiq.5kportal.com/debbieunifiq/insert_group_media.php",
							nameValuePairs);
			try {
				int success = jsonObj.getInt("success");
				if (success == 1) {
					return params[0];
				}
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			return null;
		}

	}

	/**
	 * 
	 * Starts an activity for loading a picture.
	 */
	private void loadPicture() {
		Intent intent = new Intent(Intent.ACTION_PICK,
				MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
		startActivityForResult(intent, GALLERY_REQUEST_CODE);
	}

	/** After calling intent with return value */
	@Override
	protected void onActivityResult(final int requestCode,
			final int resultCode, final Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == RESULT_OK) {
			switch (requestCode) {
			case CAMERA_REQUEST_CODE:
				draw();
				break;
			case GALLERY_REQUEST_CODE:
				mPictureFile = new File(getImagePath(data.getData()));
				draw();
				break;
			case REPLACE_IMAGE_CODE:
				Uri currImageURI = data.getData();
				System.out.println("Current image Path is "
						+ getRealPathFromURI(currImageURI));

				HttpUploader uploader = new HttpUploader();
				try {
					imagename = uploader.execute(
							getRealPathFromURI(currImageURI)).get();
					new UpdateIcon().execute();

				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (ExecutionException e) {
					e.printStackTrace();
				}

				break;
			case ADD_MEDIA_CODE:
				Uri uploadImageURI = data.getData();
				HttpUploader uploaderImg = new HttpUploader();

				try {
					imagename = uploaderImg.execute(
							getRealPathFromURI(uploadImageURI)).get();
					// get intent values
					Intent i = getIntent();
					int gid = i.getExtras().getInt("groupid");
					new UploadMedia().execute(imagename, String.valueOf(gid));
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ExecutionException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				break;
			default:
				break;
			}
		}
	}

	/** Response after choosing long click option */
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		if (item.getTitle() == "Draw on a picture") {
			loadPicture();
		} else if (item.getTitle() == "Change media") {
			mediaID = item.getItemId();
			replacePicture();
		} else if (item.getTitle() == "View comments") {
			mediaID = item.getItemId();
			Intent mIntent = new Intent(this, DrawCommentActivity.class);
			mIntent.putExtra("mediaID", String.valueOf(item.getItemId()));
			startActivity(mIntent);
		}
		return true;
	}

	/** Long click menu */
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		menu.setHeaderTitle("Media Options");
		menu.add(0, v.getId(), 0, "Draw on a picture");
		menu.add(0, v.getId(), 0, "Edit this picture");
		menu.add(0, v.getId(), 0, "Change media");
		menu.add(0, v.getId(), 0, "View comments");
	}

	/** Top right menu */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.upload_media, menu);
		return true;
	}

	/** Right menu selected */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == R.id.uploadMedia) {
			Intent intent = new Intent();
			intent.setType("image/*");
			intent.setAction(Intent.ACTION_GET_CONTENT);
			startActivityForResult(
					Intent.createChooser(intent, "Select Picture"),
					ADD_MEDIA_CODE);
		}
		return true;
	}

	/** Activity resumed */
	@Override
	public void onResume() {
		super.onResume();
	}

	/**
	 * Starts an activity for replacing picture
	 */
	private void replacePicture() {
		// To open up a gallery browser
		Intent intent = new Intent();
		intent.setType("image/*");
		intent.setAction(Intent.ACTION_GET_CONTENT);
		startActivityForResult(Intent.createChooser(intent, "Select Picture"),
				REPLACE_IMAGE_CODE);

	}

	/** Save imageview to gallery */
	private void saveImage(ImageView iv) {
		Bitmap b = iv.getDrawingCache();
		Uri path = this.getContentResolver().insert(Media.EXTERNAL_CONTENT_URI,
				new ContentValues());
		try {
			OutputStream stream = this.getContentResolver().openOutputStream(
					path);
			b.compress(CompressFormat.JPEG, 90, stream);
		} catch (FileNotFoundException e) {
			Log.e("edushare image", "E: " + e.getMessage());
		}
	}

	/**
	 * Compresses bitmap into a file.
	 * 
	 * @param bitmap
	 *            Bitmap to be compressed
	 * @return File with compressed bitmap
	 * @throws IOException
	 *             When writing to a file failed.
	 */
	private File compressBitmap(final Bitmap bitmap) throws IOException {
		File file = new File(getExternalFilesDir(null),
				GroupDetail.TMP_FILE_NAME);
		OutputStream output = null;
		try {
			output = new BufferedOutputStream(new FileOutputStream(file));
			bitmap.compress(COMPRESS_FORMAT, COMPRESS_QUALITY, output);
		} finally {
			if (output != null) {
				output.close();
			}
		}
		return file;
	}

	/** List adapter */
	private class ListAdapter extends BaseAdapter {

		LayoutInflater inflater;
		ViewHolder viewHolder;

		public ListAdapter(Context context) {
			inflater = LayoutInflater.from(context);
		}

		@Override
		public int getCount() {
			return mediaList.size();
		}

		@Override
		public Object getItem(int position) {
			return position;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			convertView = inflater.inflate(R.layout.mobile, null);
			viewHolder = new ViewHolder();

			viewHolder.media = (ImageView) convertView
					.findViewById(R.id.memberIconIV);
			viewHolder.caption = (TextView) convertView
					.findViewById(R.id.memberNameTV);
			viewHolder.pb = (ProgressBar) convertView
					.findViewById(R.id.progBar);

			convertView.setTag(viewHolder);

			viewHolder.caption.setText(mediaList.get(position).getCaption());

			// Load bitmap from internet
			URL onLineURL;
			try {
				onLineURL = new URL(mediaList.get(position).getImagePath());
				new MyNetworkTask(viewHolder.media, viewHolder.pb)
						.execute(onLineURL);
			} catch (MalformedURLException e) {
				e.printStackTrace();
			}

			/*
			 * final int temp = position;
			 * 
			 * (convertView.findViewById(R.id.groupRow)) .setOnClickListener(new
			 * OnClickListener() {
			 * 
			 * @Override public void onClick(View arg0) {
			 * 
			 * String _groupName = _groupList.get(temp) .getName().trim();
			 * String _groupdescription = _groupList.get(temp)
			 * .getDescription().trim(); String _groupimagepath =
			 * _groupList.get(temp) .getImagePath().trim();
			 * 
			 * Intent intent = new Intent(getActivity(), GroupDetail.class);
			 * 
			 * Bundle bundle = new Bundle(); bundle.putString("groupName",
			 * _groupName); bundle.putString("groupdescription",
			 * _groupdescription); bundle.putString("groupimagepath",
			 * _groupimagepath); intent.putExtras(bundle);
			 * startActivity(intent);
			 * 
			 * } });
			 */
			return convertView;

		}
	}

	/** Retrieve image from url */
	private class MyNetworkTask extends AsyncTask<URL, Void, Bitmap> {

		ImageView tIV;
		ProgressBar pb;

		public MyNetworkTask(ImageView iv, ProgressBar progBar) {
			tIV = iv;
			pb = progBar;
		}// constructor

		@Override
		protected Bitmap doInBackground(URL... urls) {

			Bitmap networkBitmap = null;

			URL networkUrl = urls[0]; // Load the first element
			try {
				networkBitmap = BitmapFactory.decodeStream(networkUrl
						.openConnection().getInputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}

			return networkBitmap;
		}// return bitmap

		@Override
		protected void onPostExecute(Bitmap result) {
			tIV.setImageBitmap(result);
			tIV.setVisibility(View.VISIBLE);
			pb.setVisibility(View.GONE);
		}// hide progress bar

	}
}